from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from sqlalchemy import func
from datetime import datetime, timedelta
from app.core.database import get_db
from app.core.deps import get_current_admin_user
from app.models.user import User
from app.models.customer import Customer
from app.models.project import Project, ProjectStatus
from app.models.contract import Contract
from app.models.visit_log import VisitLog
from typing import Dict, Any, List

router = APIRouter()

@router.get("/dashboard")
def get_dashboard_statistics(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
) -> Dict[str, Any]:
    total_customers = db.query(func.count(Customer.id)).scalar()
    
    today = datetime.now().date()
    week_ago = today - timedelta(days=7)
    new_customers = db.query(func.count(Customer.id)).filter(
        Customer.created_at >= week_ago
    ).scalar()
    
    total_projects = db.query(func.count(Project.id)).scalar()
    
    project_status_counts = {}
    for status in ProjectStatus:
        count = db.query(func.count(Project.id)).filter(
            Project.status == status
        ).scalar()
        project_status_counts[status.value] = count
    
    total_contracts = db.query(func.count(Contract.id)).scalar()
    contract_rate = (total_contracts / total_projects * 100) if total_projects > 0 else 0
    
    customers_with_multiple_projects = db.query(
        func.count(func.distinct(Project.customer_id))
    ).filter(
        Project.customer_id.in_(
            db.query(Project.customer_id).group_by(Project.customer_id).having(
                func.count(Project.id) > 1
            )
        )
    ).scalar()
    
    multiple_project_rate = (customers_with_multiple_projects / total_customers * 100) if total_customers > 0 else 0
    
    return {
        "total_customers": total_customers,
        "new_customers": new_customers,
        "total_projects": total_projects,
        "project_status_distribution": project_status_counts,
        "contract_signature_rate": round(contract_rate, 2),
        "multiple_project_customer_rate": round(multiple_project_rate, 2)
    }

@router.get("/visitors")
def get_visitor_statistics(
    days: int = 30,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
) -> Dict[str, Any]:
    start_date = datetime.now() - timedelta(days=days)
    
    daily_visits = db.query(
        func.date(VisitLog.visit_time).label('date'),
        func.count(VisitLog.id).label('count')
    ).filter(
        VisitLog.visit_time >= start_date
    ).group_by(
        func.date(VisitLog.visit_time)
    ).all()
    
    total_visits = db.query(func.count(VisitLog.id)).filter(
        VisitLog.visit_time >= start_date
    ).scalar()
    
    unique_visitors = db.query(func.count(func.distinct(VisitLog.wechat_openid))).filter(
        VisitLog.visit_time >= start_date,
        VisitLog.wechat_openid.isnot(None)
    ).scalar()
    
    return {
        "total_visits": total_visits,
        "unique_visitors": unique_visitors,
        "daily_visits": [{"date": str(date), "count": count} for date, count in daily_visits]
    }

@router.get("/customers")
def get_customer_statistics(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    total_customers = db.query(func.count(Customer.id)).scalar()
    
    customers_by_project_count = db.query(
        func.count(Project.id).label('project_count'),
        func.count(func.distinct(Project.customer_id)).label('customer_count')
    ).group_by(Project.customer_id).all()
    
    return {
        "total_customers": total_customers,
        "customers_by_project_distribution": [
            {"project_count": pc, "customer_count": cc} 
            for pc, cc in customers_by_project_count
        ]
    }

@router.get("/projects")
def get_project_statistics(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    status_distribution = {}
    for status in ProjectStatus:
        count = db.query(func.count(Project.id)).filter(
            Project.status == status
        ).scalar()
        status_distribution[status.value] = count
    
    return {
        "status_distribution": status_distribution,
        "total_projects": sum(status_distribution.values())
    }

